package org.atlantis.ymer;

import org.atlantis.ymer.event.ServerEventEmitter;
import org.atlantis.ymer.server.ConnectorServer;
import org.atlantis.ymer.server.FlashPolicyServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public final class YmerBootstrap implements Disposable {

	private static final Logger log = LoggerFactory.getLogger(YmerBootstrap.class);

	private YmerOptions options = new DefaultYmerOptions();
	private ConnectorServer connectorServer;
	private FlashPolicyServer flashPolicyServer;

	public YmerOptions getOptions() {
		return options;
	}

	public ServerEventEmitter start() {
		checkOptions();
		return startServers();
	}

	private void checkOptions() {
		if (options.getTimeoutInterval() <= 0) {
			throw new YmerException("Options error, timeoutInterval must > 0");
		}
	}

	private ServerEventEmitter startServers() {
		WebSessionFactoryImpl webSessionFactory = new WebSessionFactoryImpl(options);
		ServerEventEmitter emitter = webSessionFactory.getServerDispatcher();
		connectorServer = new ConnectorServer(webSessionFactory, options);
		connectorServer.start();
		if (!options.isFlashPolicySupport()) return emitter;
		flashPolicyServer = new FlashPolicyServer();
		flashPolicyServer.start();
		log.info("Ymer started.");
		return emitter;
	}

	@Override
	public void dispose() {
		connectorServer.dispose();
		if (flashPolicyServer != null) flashPolicyServer.dispose();
		log.info("Ymer disposed.");
	}

	private class DefaultYmerOptions implements YmerOptions {

		private long heartbeatInterval = 600000;
		private long timeoutInterval = 2000;
		private boolean flashPolicySupport = false;
		private int coreServerPort = 5656;
		private int handlerThreadSize = 16;

		@Override
		public long getHeartbeatInterval() {
			return heartbeatInterval;
		}

		@Override
		public long getTimeoutInterval() {
			return timeoutInterval;
		}

		@Override
		public int getConnectorServerPort() {
			return coreServerPort;
		}

		@Override
		public boolean isFlashPolicySupport() {
			return flashPolicySupport;
		}

		@Override
		public int getHandlerThreadSize() {
			return handlerThreadSize;
		}

		@Override
		public void setHeartbeatInterval(long heartbeatInterval) {
			this.heartbeatInterval = heartbeatInterval;
		}

		@Override
		public void setTimeoutInterval(long timeoutInterval) {
			this.timeoutInterval = timeoutInterval;
		}

		@Override
		public void setConnectorServerPort(int coreServerPort) {
			this.coreServerPort = coreServerPort;
		}

		@Override
		public void setFlashPolicySupport(boolean flashPolicySupport) {
			this.flashPolicySupport = flashPolicySupport;
		}

		@Override
		public void setHandlerThreadSize(int handlerThreadSize) {
			this.handlerThreadSize = handlerThreadSize;
		}
	}
}
